package com.ke.rule.base;

import com.ke.rule.base.ValidationException.Builder;
import org.slf4j.Logger;

/**
 * 决策执行步骤
 * 
 * @author guyu
 */
public class DecisionExecutionStep extends ServiceMethodStep implements FuncUnitActuator {

  public DecisionExecutionStep(DecisionBasedServiceMethod<?> method, Logger logger) {
    super(method, logger);
  }

  @Override
  protected Builder go() {
    return fireMatchedFuncUnits();
  }

  /**
   * 加载决策表计算出匹配的功能部件列表并执行
   * @return
   */
  private Builder fireMatchedFuncUnits() {
    Builder builder = Builder.getInstance();
    
    FuncUnitSpecBill bill = FuncUnitDecider.getMatchedFuncUnitSpecList(method.getContext(),
        method.getDecisionTableFiles(), method.getValue(), method.getOldValue(), true);
    
    if (!bill.isEmpty()) {
      FuncUnitLauncher launcher = new FuncUnitLauncher(method.getContext(), this, builder);
      launcher.fire(bill, method.getValue());
      
      method.trackExecFuncUnits(launcher.getExecutedFuncUnits());
    }
    return builder;
  }

  @SuppressWarnings({"unchecked", "rawtypes"})
  @Override
  public boolean actuate(Object value, IFuncUnit funcUnit, ValidationException.Builder builder) {
    if (method.isIdlingTest()) {
      return true;
    }
    
    if (funcUnit instanceof IProcessor) {
      IProcessor processor = (IProcessor) funcUnit;
      processor.process(method.getContext(), value);
    } else if (funcUnit instanceof IDispatcher) {
      IDispatcher dispatcher = (IDispatcher) funcUnit;
      dispatcher.dispatch(method.getContext(), value);
    } else {
      IValidator validator = (IValidator) funcUnit;
      return validator.validate(method.getContext(), value, builder);
    }
    return true;
  }

}
